﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Dotnet.Utils.Utility.Threading
{

    /// <summary>
    /// 无参数无返回委托，异步处理工具类（AsyncTaskMgr）中使用
    /// </summary>
    public delegate void VoidHandler();

    /// <summary>
    /// 异步处理工具类
    /// </summary>
    public class AsyncTaskMgr
    {
        /// <summary>
        /// 需要异步调用的方法列表
        /// </summary>
        public VoidHandler MethodCalls;
        private bool canncelTasks = false;

        public bool CanncelTasks
        {
            get { return canncelTasks; }
            set { canncelTasks = value; }
        }

        private Dictionary<Delegate, bool> dict = new Dictionary<Delegate, bool>();
        /// <summary>
        /// 开始异步调用
        /// </summary>
        public void DoAsyncWork()
        {
            Delegate[] dels = MethodCalls.GetInvocationList();
            DoAsyncWork(dels);
        }
        /// <summary>
        /// 直接传入需要执行的异步委托，开始异步调用
        /// </summary>
        /// <param name="dels">异步委托列表</param>
        public void DoAsyncWork(Delegate[] dels)
        {
            dict.Clear();
            foreach (Delegate d in dels)
            {
                if (CanncelTasks)
                {
                    break;
                }
                Task taskx = Task.Factory.StartNew(
                        delegate
                        {
                            try
                            {
                                d.DynamicInvoke();
                                dict.Add(d, true);

                            }
                            catch (Exception ex)
                            {
                                dict.Add(d, false);
                                //if (Error != null)
                                //    Error.Invoke(d, new ErrorEventArgs() { Exception = ex });
                            }
                            if (dict.Count == dels.Length)
                            {
                                if (RunComplete != null)
                                    RunComplete.Invoke(this, new EventArgs());
                            }
                        });
            }
        }
        /// <summary>
        /// 全部异步委托执行完成事件
        /// </summary>
        public event EventHandler RunComplete;
        //public event ErrorHandler Error;
    }
    /// <summary>
    /// 带参数无返回委托，异步处理工具类（AsyncTaskMgr）中使用
    /// </summary>
    public delegate void ParamHandler<T>(T p);
    /// <summary>
    /// 异步处理工具类
    /// </summary>
    /// <typeparam name="T">异步方法的泛型参数</typeparam>
    public class AsyncTaskMgr<T>
    {
        public AsyncTaskMgr()
        {

        }
        /// <summary>
        /// 需要异步调用的方法列表
        /// </summary>
        public ParamHandler<T> MethodCalls;

        private Dictionary<Delegate, bool> dict = new Dictionary<Delegate, bool>();

        /// <summary>
        /// 开始异步调用
        /// </summary>
        /// <param name="prams">异步调用时传入的参数，数量需要与MethodCalls中的参数对应</param>
        public void DoAsyncWork(params T[] prams)
        {
            Delegate del = MethodCalls as Delegate;
            if (del != null)
            {
                Delegate[] dels = del.GetInvocationList();
                DoAsyncWork(dels, prams);
            }
        }
        private bool canncelTasks = false;

        public bool CanncelTasks
        {
            get { return canncelTasks; }
            set { canncelTasks = value; }
        }

        /// <summary>
        /// 直接传入需要执行的异步委托和参数列表，开始异步调用
        /// </summary>
        /// <param name="dels">异步委托列表</param>
        /// <param name="prams">参数列表，数量需要和委托列表对应</param>
        public void DoAsyncWork(Delegate[] dels, params T[] prams)
        {
            for (int i = 0; i < dels.Length; i++)
            {
                if (CanncelTasks)
                {
                    break;
                }
                Delegate d = dels[i];
                T parm = prams[i];
                Task taskx = Task.Factory.StartNew(
                        delegate
                        {
                            try
                            {
                                d.DynamicInvoke();
                                dict.Add(d, true);
                            }
                            catch (Exception ex)
                            {
                                dict.Add(d, false);
                            }
                            if (dict.Count == dels.Length)
                            {
                                if (RunComplete != null)
                                    RunComplete.Invoke(this, new EventArgs());
                            }
                        });
            }
        }
        /// <summary>
        /// 全部异步委托执行完成事件
        /// </summary>
        public event EventHandler RunComplete;
        //public event ErrorHandler Error;
    }
}
